package main

import (
	"bufio"
	"flag"
	"net"
	logger "testProject/log"
)

const (
	RECV_BUFFER_SIZE = 512
)

func OnMessage(conn net.Conn) {

	recv_channel := make(chan []byte)
	err_channel := make(chan error)
	//先读取数据
	writer := bufio.NewWriter(conn)

	go func() {
		reader := bufio.NewReader(conn)

		for {
			buf := make([]byte, RECV_BUFFER_SIZE)
			_, error := reader.Read(buf)
			if error != nil {
				err_channel <- error
				return
			}
			recv_channel <- buf
		}
	}()

	for {
		select {
		case data, is_ok := <-recv_channel:
			if !is_ok {
				logger.Error("获取数据失败!")
				return
			}
			logger.Info("read data : %s", data)
			//这里可以启动一个写协程，即读写分离
			writer.Write(data)
			writer.Flush()
		case error_msg, is_ok := <-err_channel:
			if !is_ok {
				logger.Error("获取错误信息失败!")
				return
			}
			logger.Error(error_msg.Error())
			writer.Write([]byte(error_msg.Error()))
			writer.Flush()
		}
	}
}

func HandlerConnections(mainReactor chan net.Conn, exitSignal chan struct{}) {
	const cnt = 10

	for i := 0; i < cnt; i++ {
		go func(workID int) {
			logger.Info("工作协程ID: %d开始工作\n", workID)

			for {
				logger.Info("HandlerConnections!")
				select {

				case conn, is_ok := <-mainReactor:
					if is_ok == false {
						logger.Error("获取新连接失败!")
						continue
					}
					OnMessage(conn)
				case <-exitSignal:
					logger.Error("协程ID: %d退出!\n")
					return
				}

			}
		}(i)
	}
}
func main() {
	// 配置glog参数
	flag.Set("logtostderr", "true") // 强制所有日志输出到控制台
	flag.Set("v", "0")              // 设置日志级别为INFO(0)，显示所有INFO及以上的日志
	// 解析命令行参数
	flag.Parse()
	//主从Reactor模式
	mainReactor := make(chan net.Conn, 1000)
	exitSignal := make(chan struct{})
	//listener == 监听器
	listener, err_msg := net.Listen("tcp", "127.0.0.1:9090")
	if err_msg != nil {
		logger.Error(err_msg.Error())
	}

	//启动监听从Reactor
	go HandlerConnections(mainReactor, exitSignal)
	for {
		connection, err_msg := listener.Accept()
		if err_msg != nil {
			logger.Error(err_msg.Error())
			continue
		}
		//handler
		select {
		case mainReactor <- connection:
			logger.Info("将新连接分发至从Reactor")
		default:
			connection.Close()
			logger.Error("连接已关闭")
		}
	}
}
